package com.ruoyi.web.controller.system;

import com.alibaba.fastjson2.JSONObject;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.wx.PayService;
import com.ruoyi.common.wx.WxPayDTO;
import com.ruoyi.common.wx.WxPayProperties;
import com.ruoyi.system.domain.Orders;
import com.ruoyi.system.domain.dto.OrderDto;
import com.ruoyi.system.service.IOrdersService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Api(tags = "微信支付相关接口")
@RestController
@Validated
@RequestMapping("/system/pay")
public class WechatPayController {


    private static final Logger log = LoggerFactory.getLogger(WechatPayController.class);
    @Autowired
    private IOrdersService ordersService;
    @Resource
    private PayService payService;
    @Resource
    private WxPayProperties wxPayProperties;

    @ApiOperation(value = "微信native下单,返回支付二维码")
    @PostMapping("/nativePay")
    public Object nativePay(@RequestParam("orderNumber") String orderNumber, HttpServletRequest request) {
        //todo 业务操作-根据订单编号查询订单信息
        //将订单信息中的数据存到WxPayDTO
        WxPayDTO payDTO = new WxPayDTO();
        payDTO.setBody("商品描述");
        //订单总金额，单位为分
        payDTO.setTotalFee(1);
        //支付回调地址
        payDTO.setNotifyUrl(wxPayProperties.getNotifyUrl());
        //商品订单编号
        payDTO.setOutTradeNo(orderNumber);


        // 获取当前时间
        Date date = new Date();

        // 格式化开始时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStart = sdf.format(date);

        // 计算 30 分钟后的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, 30);
        Date expireDate = calendar.getTime();

        // 格式化结束时间
        String timeExpire = sdf.format(expireDate);

        //交易起始时间
        payDTO.setTimeStart(timeStart);
        //交易结束时间
        payDTO.setTimeExpire(timeExpire);
        Object url = payService.transactions(request, payDTO, WxPayConstants.TradeType.NATIVE);
        log.info("返回结果url:{}", url);
        return url;
    }

    @ApiOperation(value = "微信JSAPI下单,返回JS支付相关配置")
    @PostMapping("/jsapiPay")
    public Object jsapiPay(@RequestParam("orderId") String orderId,
                           @RequestParam("imageWidth") String imageWidth,
                           @RequestParam("imageHeight") String imageHeight,
                           @RequestParam("imageBottom") String imageBottom,
                           @RequestParam("imageRight") String imageRight,
                           @RequestParam("rotate") String rotate,
                           HttpServletRequest request) {

        // 获取OpenID（假设从登录用户获取）
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String openId = loginUser.getOpenId();
        log.info("openId:{}", openId);
        log.info("orderId:{}", orderId);
        log.info("imageWidth:{}", imageWidth);
        log.info("imageHeight:{}", imageHeight);
        log.info("imageBottom:{}", imageBottom);
        log.info("imageRight:{}", imageRight);
        log.info("rotate:{}", rotate);

/*        Orders order = new Orders();
        order.setOrderId(Long.valueOf(orderId));
//        order.setOrderMoney(imgType.equals("0") ? new BigDecimal("4500") : new BigDecimal("3800"));
        order.setOrderMoney(new BigDecimal("1"));
        order.setUserId(loginUser.getUserId());
        order.setOrderTime(DateUtils.getNowDate());
        order.setOrderStatus(String.valueOf(0));
        order.setUseImageName(userImg);
        order.setOrderStore(orderStore);

        ordersService.insertOrders(order);
        */

        OrderDto orderDto = ordersService.selectOrdersByOrderId(orderId);


        Orders order = new Orders();
        order.setOrderId(Long.valueOf(orderId));
        order.setImageWidth(imageWidth);
        order.setImageHeight(imageHeight);
        order.setImageBottom(imageBottom);
        order.setImageRight(imageRight);
        order.setRotate(rotate);
        ordersService.updateOrders(order);


        WxPayDTO payDTO = new WxPayDTO();
        payDTO.setBody("商品描述");
//        payDTO.setTotalFee("0".equals(orderDto.getProduct().getProductSizeType()) ? 4500 : 3800); // 单位：分
        payDTO.setTotalFee(1); // 单位：分
        payDTO.setNotifyUrl(wxPayProperties.getNotifyUrl());
        payDTO.setOutTradeNo(orderDto.getOrderId().toString()); // 订单号


        // 时间处理（与Demo一致）
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStart = sdf.format(new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, 30);
        String timeExpire = sdf.format(calendar.getTime());
        payDTO.setTimeStart(timeStart);
        payDTO.setTimeExpire(timeExpire);


        payDTO.setOpenId(openId);

        log.info("payDTO:{}", payDTO);
        log.info("openId:{}", openId);
        Object result = payService.transactions(request, payDTO, WxPayConstants.TradeType.JSAPI);
        log.info("返回结果:{}", result);
        return result;
    }

    @ApiOperation(value = "微信JSAPI下单,返回JS支付相关配置")
    @PostMapping("/pay")
    public Object pay(@RequestParam("orderId") String orderId,
                      HttpServletRequest request) {


        // 获取OpenID（假设从登录用户获取）
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String openId = loginUser.getOpenId();

        Orders order = ordersService.selectOrdersByOrderId(orderId);


        WxPayDTO payDTO = new WxPayDTO();
        payDTO.setBody("商品描述");
        payDTO.setTotalFee(Integer.valueOf(order.getOrderMoney().toString())); // 单位：分
        payDTO.setNotifyUrl(wxPayProperties.getNotifyUrl());
        payDTO.setOutTradeNo(order.getOrderId().toString()); // 订单号


        // 时间处理（与Demo一致）
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStart = sdf.format(new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, 30);
        String timeExpire = sdf.format(calendar.getTime());
        payDTO.setTimeStart(timeStart);
        payDTO.setTimeExpire(timeExpire);


        payDTO.setOpenId(openId);

        log.info("payDTO:{}", payDTO);
        log.info("openId:{}", openId);
        Object result = payService.transactions(request, payDTO, WxPayConstants.TradeType.JSAPI);
        log.info("返回结果:{}", result);
        return result;
    }

    @ApiOperation(value = "微信H5下单,返回跳转链接")
    @PostMapping("/h5Pay")
    public Object h5Pay(@RequestParam("orderNumber") String orderNumber, HttpServletRequest request) {
        //todo 业务操作-根据订单编号查询订单信息

        //将订单信息中的数据存到WxPayDTO
        WxPayDTO payDTO = new WxPayDTO();
        payDTO.setBody("商品描述");
        //订单总金额，单位为分
        payDTO.setTotalFee(1);
        //支付回调地址
        payDTO.setNotifyUrl(wxPayProperties.getNotifyUrl());
        payDTO.setOutTradeNo("商户订单号");
        //获取时间
//        Date date = new Date();
//        String timeStart = DateUtil.formatDateToString(date, "yyyyMMddHHmmss");
//        //结束时间设置在30分钟后
//        String timeExpire = DateUtil.formatDateToString(DateUtil.addMinutesToDate(date, 30),"yyyyMMddHHmmss");
        // 获取当前时间
        Date date = new Date();

        // 格式化开始时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStart = sdf.format(date);

        // 计算 30 分钟后的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, 30);
        Date expireDate = calendar.getTime();

        // 格式化结束时间
        String timeExpire = sdf.format(expireDate);
        //交易起始时间
        payDTO.setTimeStart(timeStart);
        //交易结束时间
        payDTO.setTimeExpire(timeExpire);
        //todo H5下单需要用户的用户的客户端IP
        String remoteAddr = request.getRemoteAddr();
        payDTO.setPayerClientIp(remoteAddr);
        Object url = payService.transactions(request, payDTO, WxPayConstants.TradeType.JSAPI);

        return url;
    }

    @ApiOperation(value = "微信支付回调")
    @PostMapping("/wxCallback")
    public Object wxCallback(HttpServletRequest request, HttpServletResponse response) {
        ServletInputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            String notifyXml = StreamUtils.inputStream2String(inputStream, "utf-8");
            // 解析返回结果
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyXml);
            // 判断支付是否成功
            if ("SUCCESS".equals(notifyMap.get("result_code"))) {
                log.info("-------------------------------------");
                log.info("进入SUCCESS");
                //todo 修改订单状态
                // 支付成功：给微信发送我已接收通知的响应 创建响应对象
                log.info("支付成功,微信支付回调结果:{}", JSONObject.toJSONString(notifyMap));
                Map<String, String> returnMap = new HashMap<>();
                String orderId = notifyMap.get("out_trade_no");
                String paymentNum = notifyMap.get("transaction_id");
                log.info("-------------------------------------");
                log.info("orderId：{}", orderId);
                log.info("paymentNum：{}", paymentNum);
                ordersService.payment(orderId, paymentNum);
                returnMap.put("return_code", "SUCCESS");
                returnMap.put("return_msg", "OK");
                String returnXml = WXPayUtil.mapToXml(returnMap);
                response.setContentType("text/xml");
                return returnXml;
            } else {
                String errCodeDes = notifyMap.get("err_code_des");
                // 创建响应对象：微信接收到校验失败的结果后，会反复的调用当前回调函数
                Map<String, String> returnMap = new HashMap<>();
                returnMap.put("return_code", "FAIL");
                returnMap.put("return_msg", "支付失败，具体原因：" + errCodeDes); // 添加错误描述
                String returnXml = WXPayUtil.mapToXml(returnMap);
                response.setContentType("text/xml");
                log.info("微信支付回调结果:{}", JSONObject.toJSONString(returnXml));
                return returnXml;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

